package com.samoiloff.ui.list.simple {
	import caurina.transitions.Tweener;

	import com.samoiloff.util.data.ArrItemCloneDispatcher;

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;

	/**
	 * @author Damirr
	 */
	public class ScrollCont extends ArrItemCloneDispatcher {
		
		public static const DATA_CHANGED:String = "dataChanged";
		
		protected var _anchorIndex:int;
		protected var _widthInItems:int;
		 
		protected var _data:Array;
		
		private var _anchorX:Number;
		private var _renderer:IRenderer;
		private var _width:Number;
		private var _height:Number;
		private var _itemWidth:Number;
		private var _r:Rectangle;
		private var _mc:Sprite;
		//public function ScrollCont(renderer:IRenderer, width:Number = 615, height:Number = 91, itemWidth:Number = 61, itemSpace:Number = 7) {
		public function ScrollCont(renderer:IRenderer, widthInItems:int = 8, itemWidth:Number = 68) {
			_renderer = renderer;
			
			_mc = new Sprite();
			// _mc.mouseChildren = _mc.mouseEnabled = false;
			_widthInItems = widthInItems;
			_itemWidth = itemWidth;
			
			_r = new Rectangle();
			updateValues();

			_data = [];
		}

		private function updateValues() : void {
			_width = _widthInItems * _itemWidth;
			_height = _renderer.mc.height;
			
			_r.width = _width;
			_r.height = _height;
			_mc.scrollRect = _r;
		}

		override public function destroy():void {
			Tweener.removeTweens(this);
			_data = null;
			_renderer.destroy();
			_renderer = null;
			_mc = null;
			super.destroy();
		}

		protected function updateChildren() : void {
			var minIndex : int = Math.floor(anchorX / _itemWidth);
			minIndex = minIndex < 0 ? 0 : minIndex;
			var maxIndex : int = Math.floor((anchorX + _width) / _itemWidth);
			maxIndex = maxIndex > _data.length - 1 ? _data.length - 1 : maxIndex;
			
			var i:int;
			var item:Object;
			var index:int;
			for (i = length - 1;i >= 0;i--) {
				item = getItemAt(i);
				index = item.index; 
				if (index < minIndex || index > maxIndex) {
					removeItem(item);
				}
			}
			
			for (i = minIndex;i <= maxIndex;i++) {
				if (!getItemByIndex(i)) {
					item = _renderer.instantiate();
					item.data = _data[i];
					item.index = i;
					addItem(item);
				}
			}
			
			sort();
			
			align();
		}

		override public function removeItem(item:Object):Object {
			var renderer:IRenderer = item as IRenderer;			
			super.removeItem(item);
			renderer.destroy();
			return renderer;
		}

		override public function addItem(item:Object):void {
			var renderer:IRenderer = IRenderer(item);
			_mc.addChild(renderer.mc);
			super.addItem(item);
		}

//		public function getItemByID(id:String):Object {
//			for (var i:int = 0;i < length;i++) {
//				if((getItemAt(i).data as PropItem).getValueByProp(FriendPropItem.ID) == id) {
//					return getItemAt(i); 
//				}
//			}
//			return null;//		}
//
//		public function getItem(friend:FriendPropItem):Object {
//			return getItemByID(friend.getValueByProp(FriendPropItem.ID));
//		}

		private function sort():void {
			_arr.sortOn("index");
		}

		private function align():void {
			for (var i:int = 0;i < length;i++) {
				var item : Object = getItemAt(i);
				item.mc.x = item.index * _itemWidth;
			}
		}

		private function getItemByIndex(index:int):Object {
			for (var i:int = 0;i < length;i++ ) {
				var item:Object = getItemAt(i); 
				if (item.index == index ) {
					return item; 
				}
			}
			return null;
		}
		
		public function getItemIndex(item:Object):int {
			return _data.indexOf(item);
		}

		protected function getItemAt(i:int):Object {
			return _arr[i];
		}

		public function get width() : Number {
			return _widthInItems * _itemWidth;
		}

		public function get anchorIndex():int {
			return _anchorIndex;
		}

		public function set anchorIndex(anchorIndex:int):void {
			Tweener.removeTweens(this);
			anchorX = _anchorIndex * _itemWidth;
			updateChildren();
			
			_anchorIndex = anchorIndex;
			if (_anchorIndex < 0) {
				_anchorIndex = 0;
			}
			if (_anchorIndex > _data.length - _widthInItems) {
				_anchorIndex = _data.length - _widthInItems;
			}
			dispatchEvent(new Event(Event.CHANGE));
			
			Tweener.addTween(this, {anchorX:_anchorIndex * _itemWidth, time:.5, transition:"easeInOutcubic", onUpdate:updateChildren, onComplete:updateChildren});
		}

		public function set anchorX(anchorX:Number):void {
			_anchorX = anchorX;
			_r.x = _anchorX;
//			if (!_mc) {
//				trace("ScrollCont.anchorX (anchorX ) : ");
//			}
			
			_mc.scrollRect = _r;
		}

		public function get anchorX():Number {
			return _anchorX;
		}

		public function get mc():Sprite {
			return _mc;
		}

		public function get widthInItems():int {
			return _widthInItems;
		}
		
		public function set widthInItems(widthInItems : int) : void {
			_widthInItems = widthInItems;
			updateValues();
			align();
		}

		public function get data():Array {
			return _data;
		}

		public function set itemWidth(itemWidth:Number):void {
			_itemWidth = itemWidth;
			updateValues();
			align();
		}

		public function get height():Number {
			return _height;
		}

		public function set height(height:Number):void {
			_height = height;
			updateValues();
		}
		
		public function set data(data:Array):void {
			_data = data;
			updateValues();
			anchorX = 0;
			clearChildren();
			updateChildren();
			dispatchEvent(new Event(DATA_CHANGED));
		}
		
		private function clearChildren():void {
			for (var i: int = length-1;i >= 0; i--) {
				removeItem(getItemAt(i));
			}
		}
	}
}
